import React, { useEffect } from 'react'

import "./App.css"

// 核心逻辑,排除1级菜单和当前操作节点的父菜单,其他菜单都折叠
export default function App() {
  let top;//顶级菜单(ul)根节点
  let uls;//所有菜单(ul)节点
  let as;//所有可点击(a)节点

  const expand = (element)=>{
    return ()=>{
      // 当前被点击节点的父节点
      const currentLi = retrieveParent(element, "LI")
      // 当前被点击节点旁边的兄弟节点,可能是菜单子节点(ul),也可能只是叶节点(li)
      const currentUL = currentLi.lastChild
      // 当前被点击节点的所有父节点,从子节点到根节点
      const parents = retrieveParents(element, "UL") 
      let folds = uls.filter(ul=>!parents.find(p=>p.isSameNode(ul)))
      // 当前被点击节点的兄弟节点是菜单节点时, 此节点不应该被折叠
      if(currentUL.nodeName==="UL") folds = folds.filter(ul=>!currentUL.isSameNode(ul)) 
      // 当前被点击节点的父节点的其他菜单节点都被折叠
      folds.forEach(child=>child.style.display="none")
      switchFold(currentUL, "UL")
    }
  }

  useEffect(()=>{
    const nav = document.querySelector("nav")
    top = nav.childNodes[0]
    uls = traverseChildren(top, "UL")
    as = traverseChildren(top, "A")
    as.forEach(child=>child.onclick=expand(child))
  }, [])

  // 切换节点的折叠状态
  const switchFold = (node, nodeName)=>{
    if(node.nodeName!==nodeName) return

    if(node.style.display==="block"){
      node.style.display="none"
    }else{
      node.style.display="block"
    }
  }

  const retrieveParent = (node, nodeName)=>{
    if(node && node.nodeName===nodeName){
      return node
    }else{
      return retrieveParent(node.parentNode, nodeName)
    }
  }

  const retrieveParents = (node, nodeName)=>{
    let parents = []
    if(node){
      if(node.nodeName===nodeName) {
        parents.push(node)
      }
      parents.push(...retrieveParents(node.parentNode, nodeName))
    }
    return parents
  }

  const traverseChildren = (node, nodeName)=>{
    let children = []
    let childNodes = node.childNodes
    for(let i=0; i<childNodes.length; i++){
      if(childNodes[i].nodeType===1 && childNodes[i].nodeName===nodeName){
        children.push(childNodes[i])
      }
      children.push(...traverseChildren(childNodes[i], nodeName))
    }
    return children
  }

  return (
    <nav>
    <ul>
      <li>
        <a href="#">101</a>
        <ul>
          <li>
            <a href="#">1011</a>
            <ul>
              <li><a href="#">10111</a></li>
              <li><a href="#">10112</a></li>
            </ul>
          </li>
          <li>
            <a href="#">1012</a>
            <ul>
              <li><a href="#">10121</a></li>
              <li><a href="#">10122</a></li>
            </ul>
          </li>
          <li><a href="#">1013</a></li>
        </ul>
      </li>
      <li>
        <a href="#">102</a>
        <ul>
          <li>
            <a href="#">1021</a>
            <ul>
              <li>
                <a href="#">10211</a>
                <ul>
                  <li><a href="#">102111</a></li>
                  <li><a href="#">102112</a></li>
                </ul> 
              </li>
              <li><a href="#">10212</a></li>
            </ul>
          </li>
          <li><a href="#">1022</a></li>
          <li><a href="#">1023</a></li>
        </ul>
      </li>
      <li>
        <a href="#">103</a>
        <ul>
          <li><a href="#">1031</a></li>
          <li><a href="#">1032</a></li>
          <li><a href="#">1033</a></li>
        </ul>
      </li>
    </ul>
  </nav> 
  )
}
